package ch.usi.inf.pf2.cell;


import java.util.regex.*;

/**
 *@author Matthias.Hauswirth@unisi.ch & Elham.MenzerNasr.Esfahani@usi.ch
 */

public class Recognizer

{
	private final TokenRecognizer[] recognizers;
	private String text;
	private int currentPosition;
	private Token currentToken;

	public Recognizer() {
		recognizers = new TokenRecognizer[] {
				 	new TokenRecognizer(TokenType.EQUAL, "\\="),
				 	new TokenRecognizer(TokenType.PLUS, "\\+"),
		            new TokenRecognizer(TokenType.MINUS, "\\-"),
		            new TokenRecognizer(TokenType.SLASH, "/"),
		            new TokenRecognizer(TokenType.STAR, "\\*"),
		            new TokenRecognizer(TokenType.PERCENT, "\\%"),
		            new TokenRecognizer(TokenType.OPEN_PARENTHESIS, "\\("),
		            new TokenRecognizer(TokenType.CLOSED_PARENTHESIS, "\\)"),
		            new TokenRecognizer(TokenType.CELL_REFERENCE, "\\$?[A-Z]+\\$?[0-9]+"),
		            new TokenRecognizer(TokenType.FLOATINGPOINTNUM, "[0-9]+\\.[0-9]+|[0-9]+|\\.[0-9]+")

		};
		currentPosition = 0;
	}


	/**
	 * Returns the formula operator starting at startPosition in text,
	 * or null, if there is no star operator starting at that position
	 */

	public String recognizeFormula(String text, int startPosition)

	{
		Pattern p = Pattern.compile("\\=+[a-zA-Z0-9](\\+|\\-|\\*|\\\\)*[A-Za-z0-9]*");
		Matcher m = p.matcher(text);
		boolean found = m.find(startPosition);
		if (found && m.start()==startPosition) {
			return(m.group());
		} else {
			return null;
		}
	}


	public void setText(final String text) {
		currentPosition = 0;
		currentToken = null;
		this.text = text;
		for (final TokenRecognizer r : recognizers) {
			r.setText(text);
		}
	}

	public void fetchNextToken() {
		if (currentPosition==text.length()) {
			currentToken = new Token(TokenType.END_OF_TEXT, "", currentPosition);
		} else {
			int maxTokenLength = 0;
			TokenRecognizer recognizerThatProducesTheLongestMatch = null;
			for (final TokenRecognizer r : recognizers) {
				if (r.find(currentPosition)) {
					if (r.getTokenLength()>maxTokenLength) {
						maxTokenLength = r.getTokenLength();
						recognizerThatProducesTheLongestMatch = r;
					}
				}
			}
			currentPosition += maxTokenLength;
			currentToken = recognizerThatProducesTheLongestMatch.getToken();
		}
	}

	public Token getCurrentToken() {
		return currentToken;
	}

}

